// addrspace.h 
//	Data structures to keep track of executing user programs 
//	(address spaces).
//
//	For now, we don't keep any information about address spaces.
//	The user level CPU state is saved and restored in the thread
//	executing the user program (see thread.h).
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#ifndef ADDRSPACE_H
#define ADDRSPACE_H

#include "copyright.h"
#include "filesys.h"
#include "table.h"

#define UserStackSize		1024 	// increase this as necessary!
#define NumStackPages		divRoundUp(UserStackSize,PageSize)	//Added by OceanMaster, Project2

#define MaxOpenFiles 256
#define MaxChildSpaces 256

//Added in Project3
class OnDemandTranslationEntry : public TranslationEntry
{
	public:
		bool inDisk;				//if this page is stored in swap file. even if InitData section can be saved in disk when evicted dirty
		int posId;			//Pos Id of this page in swap file.

		OnDemandTranslationEntry()
		{
			valid = false;
			use = false;
			dirty = false;
			inDisk = false;
			posId = -1;
		};
};

class AddrSpace {
  public:
    AddrSpace(OpenFile *executable);	// Create an address space,
					// initializing it with the program
					// stored in the file "executable"
    ~AddrSpace();			// De-allocate an address space

    void InitRegisters();		// Initialize user-level CPU registers,
					// before jumping to user code

    void SaveState();			// Save/restore address space-specific
    void RestoreState();		// info on a context switch
    Table fileTable;			// Table of openfiles

//-----------Project 2--------------
	int AllocateStackId();		// Allocate Stack Id for (Maybe) a new thread
	void RecycleStackId(int StackId);
					// Recycle a stack Id 
					// Note!!
					// In current Implementation, we won't reserve this stack;
					// Otherwise, we directly release these memory pages and declare there translations invalid
	unsigned int GetStackVaddr(int StackId);	// Get a stack's virtual address by stack id
	
	unsigned int GetNumPages();	//Return numPages
	unsigned int GetCodeSize();//Return numCodePages
//------------Add end---------------

//-----------Project 3--------------
	//TranslationEntry * GetVirtualPage(int vpn);	//Return Page Table Translation Entry
	int OnMissIPT(int vpn);
//------------Add end---------------
//-----------Project 3--------------
#ifndef USE_TLB
	TranslationEntry *pageTable;				// Assume linear page table translation
#else
	OnDemandTranslationEntry * pageTable;		//store more information in pageTable;
	OpenFile * myExecutable;					//store executable;
	int	CopyStartAddrInFile;					//the start address of code segment in executable file
	int CISegPages;								//Num of pages in Code and InitDate Section
	unsigned int TailSize;						//the size of last part of CI Seg
	
#endif //USE_TLB	
//------------Modify end------------

 private:

//-----------Project 2--------------
	unsigned int RootStackPage;	// Remember Root Page of Stacks
	
	int userStackNum;		// Originally, only 1 user stack is created and allocated
	int nextStackId;

	Lock * pageTableLock;
	
	//Lock * userStackLock;	
	//BitMap * userStacks;

	unsigned int codeSize;

//------------Add end---------------		
    unsigned int numPages;		// Number of pages in the virtual 
					// address space
};

#endif // ADDRSPACE_H
